package com.example;

import com.example.config.ComponentClass;
import com.example.config.DatabaseConfiguration;
import com.example.config.GlobalProperties;
import com.example.config.WebConfiguration;
import com.example.service.CustomService;
import demo.common.util.PrintUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.Map;

/**
 * 在此前我们都是通过 xml 来配置创建bean，但是当一个项目变得庞大的时候，xml的配置文件也会变得越来越大，越来越难以维护。<p>
 * 因此在项目日益庞大的现在，我们更倾向于使用一种更加简单的方式来创建与维护bean，这就是java注解的方式。<p>
 * <p>
 * {@code @ComponentScan}：等同于xml文件中的 {@code <context:component-scan>}。
 * 扫描指定包及其子包中所有贴有版型注解(@Controller、@Service、@Repository、@Component)的类，创建bean对象并交给容器管理。
 * basePackages: 指定扫描的包路径，可以指定多个。若不指定，则会扫描当前类所在的包及其子包。<p>
 *
 * @author yexi
 */
@ComponentScan(basePackages = {"com.example"})
public class AnnotationConfig {

    static {
        System.out.println("AnnotationConfig类已成功加载进内存");
    }

    public AnnotationConfig() {
        System.out.println("AnnotationConfig的无参构造器被调用: " + this);
    }

    @Autowired
    private CustomService customService;

    public static void main(String[] args) {
        try (AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AnnotationConfig.class)) {
            AnnotationConfig bean = ctx.getBean(AnnotationConfig.class);
            System.out.println("AnnotationConfig的bean对象: " + bean);
            Map<String, Object> beansWithComponent = ctx.getBeansWithAnnotation(Component.class);
            System.out.println("当前所有标注了@Component的bean: " + beansWithComponent);
            bean.methodTest();
        }
    }

    @Autowired
    private AnnotationConfig annotationConfig;

    @Autowired
    private ApplicationContext ctx;

    @Resource
    private DatabaseConfiguration.MyDataSource myDataSource;

    @Resource
    private DatabaseConfiguration.MyDataSource myDataSource2;

    @Resource
    private DatabaseConfiguration.MyDataSource myDataSource3;

    @Autowired
    private WebConfiguration.MyServer myServer;

    @Resource
    private ComponentClass componentClass;

    public void methodTest() {
        PrintUtils.println();
        System.out.println(Arrays.toString(ctx.getBeanDefinitionNames()));
        System.out.println(annotationConfig);
        System.out.println(customService.customService());
        System.out.println(myDataSource);
        System.out.println(myDataSource2);
        System.out.println(myDataSource3);
        System.out.println(ctx.getBean("myDataSource", DatabaseConfiguration.MyDataSource.class));
        System.out.println(myServer);
        System.out.println(componentClass);
        System.out.println(globalProperties.serviceName);
        System.out.println(globalProperties.serviceName2);
    }

    @Autowired
    GlobalProperties globalProperties;

}